package com.weixin.program.utils;

import com.sun.mail.util.MailSSLSocketFactory;
import lombok.extern.slf4j.Slf4j;
import org.beetl.core.Configuration;
import org.beetl.core.GroupTemplate;
import org.beetl.core.Template;
import org.beetl.core.resource.StringTemplateResourceLoader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.mail.javamail.MimeMessageHelper;

import javax.mail.Authenticator;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.GeneralSecurityException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Properties;

/**
 * @desc: <br/>
 * @author: Jingbo Hu<br/>
 * @time：2021年03⽉04⽇<br/>
 * @version：v1.0.0<br>
 */
@Slf4j
public class EmailUtil {

    private static final DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyyMMdd");

    /**
     * 发送邮件
     *
     * @param toEmailId
     * @param userName
     * @param filePath
     * @param sheetName
     * @param imagepath
     * @throws GeneralSecurityException
     * @throws MessagingException
     * @throws IOException
     */
    public static void sendEmail(String toEmailId, String userName, String gender, String filePath, String sheetName, String imagepath) throws GeneralSecurityException, MessagingException, IOException {
        // 1.创建定义整个应用程序所需要的环境信息的Session对象
        Session session = buildTransport();

        // 2.通过Session对象获取transport对象
        Transport ts = session.getTransport();

        // 3.使用邮箱的用户名和授权码连上邮件服务器
        ts.connect("smtp.qq.com", "1051064497@qq.com", "slptkagvizexbbfe");

        // 4.创建邮件
        MimeMessage message = buildEmailInfo(session, toEmailId, userName, gender, filePath, sheetName, imagepath);

        // 5.发送邮件
        ts.sendMessage(message, message.getAllRecipients());

        // 6.关闭连接
        ts.close();
    }

    /**
     * 封装邮件内容
     *
     * @param session
     * @param toEmailId
     * @param userName
     * @param filePath
     * @param sheetName
     * @param imagepath
     * @return
     * @throws MessagingException
     */
    private static MimeMessage buildEmailInfo(Session session, String toEmailId, String userName, String gender, String filePath, String sheetName, String imagepath) throws MessagingException, IOException {
        MimeMessage message = new MimeMessage(session);
        MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
        // 指定邮件的发件人
        helper.setFrom("1051064497@qq.com");

        // 指明邮件的收件人
        helper.setTo(new String[]{toEmailId});
        String excelPath = filePath + sheetName + ".xlsx";
        File file = new File(excelPath);

        // 邮件的标题
        helper.setSubject(sheetName);

        // 发送附件
        helper.addAttachment(MimeUtility.encodeWord(sheetName + ".xlsx","UTF-8","B"), file);

        // 邮件的文本内容
        helper.setText(buildContent(userName, gender, sheetName, imagepath), true);

        return message;
    }

    /**
     * 初始化邮件配置
     *
     * @return
     */
    private static Session buildTransport() throws GeneralSecurityException, NoSuchProviderException {
        Properties prop = new Properties();
        prop.setProperty("mail.host", "smtp.qq.com");
        prop.setProperty("mail.transport.protocol", "smtp");
        prop.setProperty("mail.smtp.auth", "true");

        //关于QQ邮箱，还要设置SSL加密
        MailSSLSocketFactory sf = new MailSSLSocketFactory();
        sf.setTrustAllHosts(true);
        prop.put("mail.smtp.ssl.enable", "true");
        prop.put("mail.smtp.ssl.socketFactory", sf);

        Session session = Session.getDefaultInstance(prop, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("1051064497@qq.com", "slptkagvizexbbfe");
            }
        });

        //开启Session的Debug模式,可以看到程序发送Email的运行状态
//        session.setDebug(true);
        return session;
    }

    /**
     * 封装模板内容
     *
     * @param userName
     * @param sheetName
     * @param imagepath
     * @return
     * @throws IOException
     */
    private static String buildContent(String userName, String gender, String sheetName, String imagepath) throws IOException {
        //这个方法只能从类路径下获取文件,无法从jar包中获取,所以打成jar包后发布到linuxs系统,就报错找不到文件了
//        File file = ResourceUtils.getFile("classpath:static/noticemail.html");
        ClassPathResource resource = new ClassPathResource("static/noticemail.html");
        InputStreamReader streamReader = new InputStreamReader(resource.getInputStream(), "UTF-8");
        BufferedReader fileReader = new BufferedReader(streamReader);
        StringBuffer buffer = new StringBuffer();
        String line = "";
        try {
            while ((line = fileReader.readLine()) != null) {
                buffer.append(line);
            }
        } catch (Exception e) {
            log.error("读取Html模板内容失败,错误信息:{}", e);
        } finally {
            fileReader.close();
        }

        // 在HTML指定位置新增标签
        String htmlContent = buffer.toString();
        htmlContent = HtmlUtil.buildHtml(htmlContent, imagepath);

        //初始化代码
        StringTemplateResourceLoader resourceLoader = new StringTemplateResourceLoader();
        Configuration cfg = Configuration.defaultConfiguration();
        GroupTemplate gt = new GroupTemplate(resourceLoader, cfg);
        //替换模板中变量
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate localDate = LocalDate.now();
        Template t = gt.getTemplate(htmlContent);
        t.binding("userName", userName);
        t.binding("gender", gender);
        t.binding("record", sheetName);
        t.binding("dateTime", localDate.format(fmt));
        //渲染结果
        String str = t.render();
        return str;
    }
}
